<template>
  <div id="articleManageView">
    <!--搜索文章-->
    <a-form :model="searchParams" layout="inline" class="searchArticleForm">
      <a-form-item field="title" label="标题" tooltip="模糊匹配">
        <a-input
          v-model="searchParams.title"
          placeholder="请输入文章标题"
          allow-clear
        />
      </a-form-item>
      <a-form-item
        v-if="currentUser.userRole === ROLE_ENUM.ADMIN"
        field="userId"
        label="作者"
        tooltip="精确匹配"
      >
        <a-input
          v-model="searchParams.userId"
          placeholder="请输入用户Id"
          allow-clear
        />
      </a-form-item>
      <a-form-item field="auditStatus" label="审核">
        <a-select
          :style="{ width: '180px' }"
          v-model="searchParams.auditStatus"
          placeholder="请选择审核状态"
          allow-clear
        >
          <a-option value="0">待审核</a-option>
          <a-option value="1">审核通过</a-option>
          <a-option value="2">不通过</a-option>
        </a-select>
      </a-form-item>
      <a-form-item field="publicStatus" label="发布状态">
        <a-select
          :style="{ width: '180px' }"
          v-model="searchParams.publicStatus"
          placeholder="请选择发布状态"
          allow-clear
        >
          <a-option value="0">上架</a-option>
          <a-option value="1">下架</a-option>
        </a-select>
      </a-form-item>
      <a-form-item>
        <a-button
          type="outline"
          shape="round"
          status="normal"
          @click="doSearch"
        >
          搜索
        </a-button>
      </a-form-item>
      <a-form-item>
        <a-button type="primary" @click="doEditArticle()"> 写文章</a-button>
      </a-form-item>
    </a-form>
    <!--文章表格-->
    <a-table
      :columns="columns"
      :data="data"
      :pagination="pagination"
      @page-change="onPageChange"
      column-resizable
      filter-icon-align-left
    >
      <template #title="{ record }">
        <a-link :href="`/article/detail/${record.id}`"
          >{{ record.title }}
        </a-link>
      </template>
      <template #auditStatus="{ record }">
        <a-tag color="orange" v-if="record.auditStatus === 0"> 待审核</a-tag>
        <a-tag color="green" v-else-if="record.auditStatus === 1">
          审核通过
        </a-tag>
        <a-link v-else status="danger" @click="catReason(record.id)">
          驳回（点击查看原因）
        </a-link>
      </template>
      <template #shelfState="{ record }">
        <a-switch
          v-model="record.publicStatus"
          :checked-value="0"
          :unchecked-value="1"
          @change="doUpdateShelfState(record.id)"
        >
          <template #checked> 已上架</template>
          <template #unchecked> 已下架</template>
        </a-switch>
      </template>
      <template #createTime="{ record }">
        {{ dayjs(record.createTime).format("YYYY-MM-DD HH:mm:ss") }}
      </template>
      <template #updateTime="{ record }">
        {{ dayjs(record.updateTime).format("YYYY-MM-DD HH:mm:ss") }}
      </template>
      <template #optional="{ record }">
        <a-space>
          <a-button
            v-if="
              currentUser.userRole === ROLE_ENUM.ADMIN &&
              record.userVO.userRole !== 'admin'
            "
            type="primary"
            status="danger"
            shape="round"
            @click="handleAuditBtn(record.id)"
            >审批
          </a-button>
          <a-button
            type="primary"
            status="success"
            shape="round"
            @click="doEditArticle(record.id)"
          >
            编辑
          </a-button>
        </a-space>
      </template>
    </a-table>
    <!--审批模态框-->
    <a-modal
      width="590px"
      v-model:visible="auditModelVisible"
      title="审批"
      @cancel="handleCancel"
      @before-ok="handleBeforeOk"
      @ok="handleAuditOK"
    >
      <div class="radio-group-content">
        <a-radio-group
          default-value="1"
          v-model="auditForm.auditStatus"
          @change="handleRadioChange"
        >
          <a-radio value="1">
            <template #radio="{ checked }">
              <a-space
                align="start"
                class="custom-radio-card"
                :class="{ 'custom-radio-card-checked': checked }"
              >
                <div class="custom-radio-card-mask">
                  <div class="custom-radio-card-mask-dot" />
                </div>
                <div>
                  <div class="custom-radio-card-title">审批通过</div>
                  <a-typography-text type="secondary">
                    无需填写原因，直接审核通过
                  </a-typography-text>
                </div>
              </a-space>
            </template>
          </a-radio>
          <a-radio value="2">
            <template #radio="{ checked }">
              <a-space
                align="start"
                class="custom-radio-card"
                :class="{ 'custom-radio-card-checked': checked }"
              >
                <div class="custom-radio-card-mask">
                  <div class="custom-radio-card-mask-dot" />
                </div>
                <div>
                  <div class="custom-radio-card-title">驳回</div>
                  <a-typography-text type="secondary">
                    请填写驳回原因
                  </a-typography-text>
                </div>
              </a-space>
            </template>
          </a-radio>
        </a-radio-group>
      </div>
      <a-textarea
        v-if="auditForm.auditStatus == 2"
        v-model="auditForm.result"
        placeholder="请输入驳回原因..."
        :max-length="{ length: 1024, errorOnly: true }"
        allow-clear
        show-word-limit
      />
    </a-modal>
    <!--驳回原因抽屉-->
    <a-drawer
      :width="340"
      :height="340"
      :visible="rejectDrawerVisible"
      @ok="handleRejectDrawerCancel"
      hide-cancel
      :closable="false"
      unmountOnClose
    >
      <template #title> 驳回原因</template>
      <div>
        {{ rejectReason }}
      </div>
    </a-drawer>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, watchEffect } from "vue";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import { useRouter } from "vue-router";
import { useStore } from "vuex";
import ROLE_ENUM from "@/access/ROLE_ENUM";
import { ArticleControllerService } from "../../../generated";
import { Message } from "@arco-design/web-vue";

const router = useRouter();
const store = useStore();

// 当前登录用户
const currentUser = ref(store.state.user.loginUser);

// 表格列
const columns = [
  {
    slotName: "title",
    title: "标题",
  },
  {
    dataIndex: "userId",
    title: "作者",
    align: "center",
    ellipsis: true,
    tooltip: true,
  },
  {
    dataIndex: "thumbNum",
    title: "点赞数",
    align: "center",
  },
  {
    slotName: "auditStatus",
    title: "审核状态",
    align: "center",
  },
  {
    slotName: "shelfState",
    title: "上架状态",
    align: "center",
  },
  {
    title: "创建时间",
    width: 125,
    align: "center",
    ellipsis: true,
    tooltip: true,
    slotName: "createTime",
    sortable: {
      sortDirections: ["ascend", "descend"],
    },
  },
  {
    title: "更新时间",
    width: 125,
    align: "center",
    ellipsis: true,
    tooltip: true,
    slotName: "updateTime",
    sortable: {
      sortDirections: ["ascend", "descend"],
    },
  },
  {
    title: "操作",
    align: "center",
    ellipsis: true,
    tooltip: true,
    slotName: "optional",
  },
];
// 数据列表
const data = ref([]);

// 搜索表单
const searchParams = ref({
  current: 1,
  pageSize: 10,
  title: "",
  userId: null,
  auditStatus: null,
  publicStatus: null,
});

// 分页结果参数
let pagination = reactive({
  showTotal: true,
  current: 0,
  pageSize: 0,
  total: 0,
});

// 加载数据
const loadData = async () => {
  const res = await ArticleControllerService.listArticleByPageUsingPost(
    searchParams.value as any
  );
  if (res.code === 0) {
    // 数据赋值
    data.value = res.data.records;
    // 分页结果参数赋值
    pagination.total = Number(res.data.total);
    pagination.current = Number(res.data.current);
    pagination.pageSize = Number(res.data.size);
  } else {
    Message.error("获取数据失败，" + res.message);
  }
};

/**
 * 搜索
 */
const doSearch = () => {
  // 这里需要重置页号，不然你在第二页搜索第一页的内容，会搜不到
  searchParams.value = {
    ...searchParams.value,
    current: 1,
  };
};

/**
 * 监听 () => { } 中的内容，
 * 内容中的变量（例如searchParams）发生改变时会再次触发() => { }中的内容（即loadData()重新加载数据）
 */
watchEffect(() => {
  loadData();
});

/**
 * 页码改变时触发
 */
const onPageChange = (page: number) => {
  searchParams.value = {
    ...searchParams.value,
    current: page,
  };
};

/**
 * 写文章、编辑文章
 * @param id 文章id
 */
const doEditArticle = (id?: number) => {
  // 如果没有id，就是新增，否则就是编辑
  if (id == null) {
    router.push({
      path: "/article/add",
    });
  } else {
    router.push({
      path: "/article/update",
      query: {
        id,
      },
    });
  }
};

/**
 * 上下架文章
 * @param id 文章id
 */
const doUpdateShelfState = async (id: number) => {
  const res = await ArticleControllerService.deleteArticleUsingPost({
    id: id,
  });
  if (res.code !== 0) Message.error("修改状态失败，" + res.message);
};

// 审批模态框
const auditModelVisible = ref(false);

// 审批表单
let auditForm = ref({
  id: null,
  auditStatus: "1",
  result: "",
});

/**
 * 选择审批状态改变时触发
 * @param v 选中的值
 */
const handleRadioChange = (v: any) => {
  auditForm.value.auditStatus = v;
};

// 审批模态框的取消按钮
const handleCancel = () => {
  auditModelVisible.value = false;
};

/**
 * 审批文章按钮
 * @param id 文章id
 */
const handleAuditBtn = async (id: any) => {
  auditModelVisible.value = true;
  auditForm.value.id = id;
};

/**
 * 审批文章模态框确定按钮之前的判断
 * @param done 确定按钮回调
 */
const handleBeforeOk = (done: (closed: boolean) => void) => {
  if (auditForm.value.auditStatus == "2" && auditForm.value.result == "") {
    Message.error("请输入驳回原因");
    done(false);
    return;
  }
  done(true);
};

/**
 * 审核文章确定按钮
 */
const handleAuditOK = async () => {
  const res = await ArticleControllerService.auditArticleUsingPost(
    auditForm.value as any
  );
  if (res.code === 0) {
    await loadData();
    Message.success("审核成功");
  } else {
    Message.error("审核失败，" + res.message);
  }
};

// 驳回原因文本
const rejectReason = ref("");

// 驳回原因抽屉
const rejectDrawerVisible = ref(false);

/**
 * 驳回原因抽屉取消按钮
 */
const handleRejectDrawerCancel = () => {
  rejectDrawerVisible.value = false;
};

/**
 * 查看驳回原因
 */
const catReason = async (id: any) => {
  const res = await ArticleControllerService.getRejectReasonByIdUsingGet(id);
  if (res.code === 0) {
    rejectReason.value = res.data;
    rejectDrawerVisible.value = true;
  } else {
    Message.error("获取失败，" + res.message);
  }
};
</script>

<style scoped>
/*搜索文章表单*/
.searchArticleForm {
  justify-content: center;
  align-content: center;
  margin-bottom: 20px;
}

.radio-group-content {
  margin-bottom: 15px;
}

.custom-radio-card {
  padding: 10px 16px;
  border: 1px solid var(--color-border-2);
  border-radius: 4px;
  width: 250px;
  box-sizing: border-box;
}

.custom-radio-card-mask {
  height: 14px;
  width: 14px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 100%;
  border: 1px solid var(--color-border-2);
  box-sizing: border-box;
}

.custom-radio-card-mask-dot {
  width: 8px;
  height: 8px;
  border-radius: 100%;
}

.custom-radio-card-title {
  color: var(--color-text-1);
  font-size: 14px;
  font-weight: bold;
  margin-bottom: 8px;
}

.custom-radio-card:hover,
.custom-radio-card-checked,
.custom-radio-card:hover .custom-radio-card-mask,
.custom-radio-card-checked .custom-radio-card-mask {
  border-color: rgb(var(--primary-6));
}

.custom-radio-card-checked {
  background-color: var(--color-primary-light-1);
}

.custom-radio-card:hover .custom-radio-card-title,
.custom-radio-card-checked .custom-radio-card-title {
  color: rgb(var(--primary-6));
}

.custom-radio-card-checked .custom-radio-card-mask-dot {
  background-color: rgb(var(--primary-6));
}
</style>